"""
定位后台服务器
支持WebSocket通信，可以向App发送定位指令并接收位置上报
"""
from flask import Flask, render_template, request, jsonify
from flask_socketio import SocketIO, emit, join_room, leave_room
from flask_cors import CORS
from datetime import datetime
import json
import os

app = Flask(__name__)

# 加载配置
try:
    from config import get_config
    config_obj = get_config()
    app.config.from_object(config_obj)
except ImportError:
    # 如果没有config.py，使用默认配置
    app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'your-secret-key-here')
    app.config['CORS_ALLOWED_ORIGINS'] = os.getenv('CORS_ORIGINS', '*')
    app.config['PING_TIMEOUT'] = 60
    app.config['PING_INTERVAL'] = 25
    app.config['MAX_HISTORY_PER_DEVICE'] = 100

# 配置CORS
CORS(app, origins=app.config.get('CORS_ALLOWED_ORIGINS', '*'))

# 配置SocketIO
socketio = SocketIO(
    app, 
    cors_allowed_origins=app.config.get('CORS_ALLOWED_ORIGINS', '*'),
    ping_timeout=app.config.get('PING_TIMEOUT', 60),
    ping_interval=app.config.get('PING_INTERVAL', 25)
)

# 存储连接的设备信息
connected_devices = {}
# 存储设备最新位置
device_locations = {}
# 存储位置历史记录（最多保存每个设备100条）
location_history = {}

@app.route('/')
def index():
    """管理界面首页"""
    return render_template('index.html')

@app.route('/api/devices')
def get_devices():
    """获取所有连接的设备列表"""
    devices = []
    for device_id, info in connected_devices.items():
        device_data = {
            'device_id': device_id,
            'device_name': info.get('device_name', '未知设备'),
            'connected_at': info.get('connected_at'),
            'last_update': info.get('last_update'),
        }
        # 添加最新位置信息
        if device_id in device_locations:
            device_data['location'] = device_locations[device_id]
        devices.append(device_data)
    return jsonify({'devices': devices})

@app.route('/api/device/<device_id>/history')
def get_device_history(device_id):
    """获取指定设备的位置历史"""
    history = location_history.get(device_id, [])
    return jsonify({'device_id': device_id, 'history': history})

@app.route('/api/device/<device_id>/request-location', methods=['POST'])
def request_device_location(device_id):
    """向指定设备发送定位请求"""
    if device_id not in connected_devices:
        return jsonify({'success': False, 'error': '设备未连接'}), 404
    
    # 通过WebSocket发送定位指令
    socketio.emit('request_location', {
        'timestamp': datetime.now().isoformat(),
        'message': '请上报当前位置'
    }, room=device_id)
    
    return jsonify({'success': True, 'message': f'已向设备 {device_id} 发送定位请求'})

@socketio.on('connect')
def handle_connect():
    """客户端连接"""
    print(f'客户端连接: {request.sid}')
    emit('connection_response', {
        'status': 'connected',
        'sid': request.sid,
        'message': '连接成功'
    })

@socketio.on('disconnect')
def handle_disconnect():
    """客户端断开连接"""
    print(f'客户端断开: {request.sid}')
    # 从连接设备列表中移除
    if request.sid in connected_devices:
        device_info = connected_devices[request.sid]
        print(f'设备断开: {device_info.get("device_name", "未知设备")}')
        del connected_devices[request.sid]

@socketio.on('register_device')
def handle_register_device(data):
    """设备注册"""
    device_id = request.sid
    device_name = data.get('device_name', '未知设备')
    device_model = data.get('device_model', '')
    android_version = data.get('android_version', '')
    
    connected_devices[device_id] = {
        'device_name': device_name,
        'device_model': device_model,
        'android_version': android_version,
        'connected_at': datetime.now().isoformat(),
        'last_update': datetime.now().isoformat()
    }
    
    # 将设备加入自己的房间
    join_room(device_id)
    
    print(f'设备注册成功: {device_name} (ID: {device_id})')
    
    emit('register_response', {
        'success': True,
        'device_id': device_id,
        'message': '设备注册成功'
    })
    
    # 通知所有管理端有新设备连接
    socketio.emit('device_connected', {
        'device_id': device_id,
        'device_name': device_name,
        'timestamp': datetime.now().isoformat()
    }, broadcast=True, include_self=False)

@socketio.on('report_location')
def handle_report_location(data):
    """接收设备上报的位置信息"""
    device_id = request.sid
    
    if device_id not in connected_devices:
        emit('error', {'message': '设备未注册'})
        return
    
    # 提取位置信息
    location_data = {
        'latitude': data.get('latitude'),
        'longitude': data.get('longitude'),
        'accuracy': data.get('accuracy'),
        'timestamp': data.get('timestamp', datetime.now().isoformat()),
        'address': data.get('address', ''),
        'location_name': data.get('location_name', ''),
        'is_simulated': data.get('is_simulated', False)
    }
    
    # 更新设备最新位置
    device_locations[device_id] = location_data
    
    # 更新设备最后更新时间
    connected_devices[device_id]['last_update'] = datetime.now().isoformat()
    
    # 添加到历史记录
    if device_id not in location_history:
        location_history[device_id] = []
    
    location_history[device_id].append(location_data)
    
    # 只保留最近N条记录（从配置读取）
    max_history = app.config.get('MAX_HISTORY_PER_DEVICE', 100)
    if len(location_history[device_id]) > max_history:
        location_history[device_id] = location_history[device_id][-max_history:]
    
    device_name = connected_devices[device_id].get('device_name', '未知设备')
    print(f'收到位置上报 - 设备: {device_name}, 位置: ({location_data["latitude"]}, {location_data["longitude"]})')
    
    # 向客户端确认收到
    emit('location_received', {
        'success': True,
        'message': '位置已接收',
        'timestamp': datetime.now().isoformat()
    })
    
    # 广播位置更新到所有管理端
    socketio.emit('location_update', {
        'device_id': device_id,
        'device_name': device_name,
        'location': location_data
    }, broadcast=True, include_self=False)

@socketio.on('ping')
def handle_ping():
    """处理心跳包"""
    emit('pong', {'timestamp': datetime.now().isoformat()})

if __name__ == '__main__':
    # 从配置或环境变量获取参数
    host = app.config.get('HOST', os.getenv('HOST', '0.0.0.0'))
    port = int(app.config.get('PORT', os.getenv('PORT', 5000)))
    debug = app.config.get('DEBUG', os.getenv('DEBUG', 'True').lower() == 'true')
    
    print('=' * 60)
    print('定位后台服务器启动')
    print(f'管理界面: http://{host}:{port}')
    print(f'WebSocket地址: ws://{host}:{port}')
    print(f'环境: {"开发" if debug else "生产"}')
    print('=' * 60)
    
    socketio.run(app, host=host, port=port, debug=debug, allow_unsafe_werkzeug=True)

